from django.http import HttpResponseRedirect
from django.utils.encoding import smart_unicode
from django.core.urlresolvers import reverse

from openid.consumer.consumer import Consumer, SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
from openid.consumer.discover import DiscoveryFailure
from openid.store.memstore import MemoryStore

import settings
from djangoopenid.utils import render_response
from djangoopenid.utils import get_url_host
from djangoopenid.decorators import *

class OpenIDSessions(object):
  memoryStore = MemoryStore()

sessionStore = None
if hasattr(settings, 'OPENID_SESSIONS_TO_CLEAN'):
  sessions_to_clean = settings.OPENID_SESSIONS_TO_CLEAN
  sessionStore = OpenIDSessions.memoryStore

@begin_development_environment
def begin(request):
  if request.method == 'GET':
    return render_response(request, 'djangoopenid/please_login.html')
  # POST
  consumer = Consumer(request.session, sessionStore)
  try:
    openidurl = request.POST['openidurl'].lower()
    authrequest = consumer.begin(openidurl)
    sufix = reverse('djangoopenid.views.complete', args=None)
    host = get_url_host(request)
    # host = request.get_host() django 1.0
    return_to = host + sufix
    redirectURL = authrequest.redirectURL(host, 
                                          return_to, 
                                          immediate=False)
    return HttpResponseRedirect(redirectURL)
  except DiscoveryFailure:
    return render_response(request, 'djangoopenid/please_login.html', 
                           {'openidMessage': 'Invalid OpenID'})

@complete_development_environment
def complete(request):
  consumer = Consumer(request.session, sessionStore)
  params = dict((k,smart_unicode(v)) for k, v in request.GET.items())
  sufix = reverse('djangoopenid.views.complete', args=None)
  return_to = get_url_host(request) + sufix
  openidresponse = consumer.complete(params, return_to)
  # FIXME: cron job?
  if sessionStore is not None and len(OpenIDSessions.memoryStore.server_assocs) % sessions_to_clean == 0:
    OpenIDSessions.memoryStore.cleanupAssociations()
    OpenIDSessions.memoryStore.cleanupNonces()
  ##
  if openidresponse.status == SUCCESS:
    request.session['openiduser'] = openidresponse.getDisplayIdentifier()
    return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
  elif openidresponse.status == FAILURE: 
    openidMessage = openidresponse.status + ': ' + openidresponse.message
  elif openidresponse.status == CANCEL: 
    openidMessage = openidresponse.status
  elif openidresponse.status == SETUP_NEEDED:
    openidMessage = openidresponse.status
  openidMessage = 'OpenID status: ' + openidMessage
  return render_response(request, 'djangoopenid/please_login.html', 
                         {'openidMessage': openidMessage})

@openid_login_required
def logout(request):
  if hasattr(request.session, 'openid'):
    del(request.session['openiduser'])
  if hasattr(request.session, 'user'):
    del(request.session['user'])
  request.session.flush()
  return HttpResponseRedirect(settings.LOGOUT_URL)

